package com.crm.task.executer;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.crm.common.CrmInit;
import com.crm.task.beans.CrmStream;
import com.crm.util.DateEx;

public class DBBackupExecuter implements Job {

	private static Logger logger = Logger.getLogger(DBBackupExecuter.class);
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");

	private static String dbname = CrmInit.DB_NAME;
	private static String username = CrmInit.DB_USERNAME;
	private static String password = CrmInit.DB_PASSWORD;
	private static String binPath = CrmInit.DB_BACKUPBIN_PATH;
	private static String storePath = CrmInit.DB_BACKUPSTORE_PATH;

	private static String mailHost = CrmInit.MAIL_HOST;
	private static String mailMaster = CrmInit.MAIL_MASTER;
	private static String mailReceive = CrmInit.MAIL_RECEIVE;
	private static String mailPassword = CrmInit.MAIL_PASSWORD;
	private static String mailTitle = CrmInit.MAIL_TITLE;
	private static String mailContext = CrmInit.MAIL_CONTEXT;

	private static String backupDBToLocale() {
		String curDate = dateFormat.format(new Date());
		String backupFileName = "CRM-" + curDate + ".sql";
		logger.info("Begin backup DB : " + DateEx.getCurDateTime());
		String cmd = "cmd /c " + binPath + " -u " + username + " -p" + password + " --opt " + dbname + " -r"
				+ storePath + backupFileName;
		logger.info("Begin backup DB cmd : " + cmd);
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(cmd);
			CrmStream outGobbler = new CrmStream(process.getInputStream(), "STDOUT");
			outGobbler.start();
			CrmStream errorGobbler = new CrmStream(process.getErrorStream(), "ERROR");
			errorGobbler.start();

			process.waitFor();
			curDate = dateFormat.format(new Date());
			logger.info("End backup DB : " + DateEx.getCurDateTime() + ", backup file : " + backupFileName);
		} catch (Exception e) {
			logger.error("DBBackupExecuter.backupMySql has error:", e);
			return null;
		}
		return backupFileName;
	}

	private static void backupDBToMail(String backupFileName) {
		try {
			String curDate = DateEx.getCurDateTime();
			logger.info("Begin backup DB mail : " + curDate);
			String title = MessageFormat.format(mailTitle, curDate);
			String text = MessageFormat.format(mailContext, curDate);

			Properties props = new Properties();
			props.put("mail.smtp.host", mailHost);
			props.put("mail.smtp.auth", "true");
			Session session = Session.getDefaultInstance(props);
			session.setDebug(false);
			MimeMessage message = new MimeMessage(session);
			message.setFrom(new InternetAddress(mailMaster));
			message.addRecipient(Message.RecipientType.TO, new InternetAddress(mailReceive));
			message.setSubject(title);
			Multipart multipart = new MimeMultipart();
			BodyPart contentPart = new MimeBodyPart();
			contentPart.setText(text);
			multipart.addBodyPart(contentPart);
			BodyPart messageBodyPart = new MimeBodyPart();
			DataSource source = new FileDataSource(storePath + backupFileName);
			messageBodyPart.setDataHandler(new DataHandler(source));
			messageBodyPart.setFileName(MimeUtility.encodeText(backupFileName));
			multipart.addBodyPart(messageBodyPart);
			message.setContent(multipart);
			message.saveChanges();
			Transport transport = session.getTransport("smtp");
			transport.connect(mailHost, mailMaster, mailPassword);
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
			logger.info("End backup DB mail : " + DateEx.getCurDateTime());
		} catch (Exception e) {
			logger.error("DBBackupExecuter.backupDBToMail has error:", e);
		}
	}

	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		String backupFileName = DBBackupExecuter.backupDBToLocale();
		// if (backupFileName == null || backupFileName.trim().isEmpty()) {
		// return;
		// }
		// try {
		// TimeUnit.SECONDS.sleep(5L);
		// } catch (InterruptedException e) {
		// logger.error("DBBackupExecuter.TimeUnit.SECONDS.sleep(5L) has error:",
		// e);
		// }
		// DBBackupExecuter.backupDBToMail(backupFileName);
	}

}
